type Param={
	url:string;
	callback:(data:any)=>void;
	msg?:string;
}
class CreateSocket {
	private websocket:WebSocket|undefined;
	private lockReconnect:boolean = false; // 重连锁定
	private timeout:number = 10000;
	private timer:number|undefined; // 重连定时器
	private checkTimer:number|undefined; // 心跳检测发送定时器
	private serverCheckTimer:number|undefined; // 心跳检测响应定时器
	private isActivelyClose:boolean = false; // 是否是手动关闭
	private param:Param;
	constructor(param:Param) {
		this.param = param;
	}
	// 连接websocket
	connect() {
		this.isActivelyClose = false;
		this.initSocket();
	}
	// 初始化websocket
	initSocket() {
		this.websocket = new WebSocket(this.param.url);
		this.websocket.onclose = () => {
			console.log(this.param.url + '--websocket已关闭！');
			// 如果是手动关闭则不再进行重连
			if (!this.isActivelyClose) {
				this.reconnectSocket();
			}
		};
		this.websocket.onerror = e => {
			console.log(this.param.url + '--websocket发生异常！');
			// 如果是手动关闭则不再进行异常重连
			if (!this.isActivelyClose) {
				this.reconnectSocket();
			}
		};
		this.websocket.onopen = () => {
			console.log(this.param.url + '--websocket已连接！');
			this.heartCheck();
			if (this.param.msg) this.send(this.param.msg);
		};
		this.websocket.onmessage = e => {
			this.heartCheck();
			// console.log('ws接收数据:' + e.data);
			if (e.data.length < 5) return;
			this.param.callback(JSON.parse(e.data));
		};
	}
	// 重新连接
	reconnectSocket() {
		if (this.lockReconnect) return;
		console.log(this.param.url + '--websocket正在进行重新连接...');
		this.lockReconnect = true;
		this.timer && clearTimeout(this.timer);
		this.timer = window.setTimeout(() => {
			this.initSocket();
			this.lockReconnect = false;
		}, this.timeout);
	}
	// 发送数据
	send(msg:string) {
		this.websocket && this.websocket.send(JSON.stringify(msg));
	}
	// 心跳检测
	heartCheck() {
		this.checkTimer && clearTimeout(this.checkTimer);
		this.serverCheckTimer && clearTimeout(this.serverCheckTimer);
		this.checkTimer = window.setTimeout(() => {
			// 发送一个心跳，后端返回一个心跳消息，onmessage拿到返回的心跳说明连接正常
			this.websocket && this.websocket.send('ping');
			this.serverCheckTimer = window.setTimeout(() => {
				// 后端无心跳消息返回，关闭websocket
				this.websocket && this.websocket.close();
			}, this.timeout);
		}, this.timeout);
	}
	// 手动关闭websocket
	close() {
		this.isActivelyClose = true;
		this.websocket && this.websocket.close();
	}
}

export default CreateSocket;

